export interface IOptions {
    id?: string; // 元素 ID
    className?: string; // 元素 ClassName
    innerClassName?: string; // 组件 ShadowRoot 元素 ClassName

    templateId?: string; // 嵌入组件内部的模板 ID
    templateData?: Record<string, unknown>; // 组件内部模板参数编译

    cache?: boolean; // 是否缓存组件，即是否关闭时销毁组件（默认缓存）
}

class Dialog {
    // ...
    options: IOptions;

    // 对话框元素
    dialogEle?: null | HTMLElement;
    // 组件内部封装元素
    dialogWrapEle?: null | HTMLElement;
    // 嵌入组件内部的模板元素
    slotTemplateEle?: null | HTMLTemplateElement;

    constructor(options?: IOptions) {
        // ...
        this.options = options || {};

        this.initDialogEle();
        this.setDialogEleAttrs();

        this.bindEvents();
    }

    /**
     * 绑定事件
     */
    bindEvents(): void {
        const closeProxy = window._webcEvent?.dialog?.close;

        window._webcEvent.dialog = {
            close: () => {
                this.closeDialog();
                closeProxy?.();
            },
        };
    }

    /**
     * 打开对话框
     */
    openDialog(): void {
        if (this.dialogEle) {
            this.dialogEle.style.display = 'block';
        }
    }

    /**
     * 关闭对话框
     */
    closeDialog(): void {
        if (this.dialogEle) {
            this.dialogEle.style.display = 'none';
            if (this.options.cache === false) {
                document.body.removeChild(this.dialogEle);
            }
        }
    }

    /**
     * 检索是否已存在元素，复用元素
     */
    initDialogEle(): void {
        if (this.options.id) {
            const hasSameDialogEle = document.querySelector(`#${this.options.id}`) as HTMLElement | null;
            if (hasSameDialogEle) {
                this.dialogEle = hasSameDialogEle;
            } else {
                this.createDialogEle();
            }
        } else {
            const hasDialogEle = document.querySelector('webc-dialog') as HTMLElement | null;
            if (hasDialogEle) {
                this.dialogEle = hasDialogEle;
            } else {
                this.createDialogEle();
            }
        }

        if (this.dialogEle) {
            this.dialogWrapEle = this.dialogEle.shadowRoot?.querySelector('.webc-dialog-wrapper') as HTMLElement | null;
        }
    }

    /**
     * 创建对话框元素
     */
    createDialogEle(): void {
        const proxyEle = document.createElement('div');
        proxyEle.innerHTML = '<webc-dialog></webc-dialog>';

        this.dialogEle = proxyEle.querySelector('webc-dialog') as HTMLElement | null;

        if (this.dialogEle) {
            // ...
            this.slotTemplateEle = document.querySelector(`#${this.options.templateId}`) as HTMLTemplateElement | null;
            if (this.slotTemplateEle) {
                // 模板参数编译
                if (this.options.templateData) {
                    const templateContent = this.slotTemplateEle.innerHTML;
                    let tmp = templateContent;
                    for (const field in this.options.templateData) {
                        const regExp = new RegExp(`{ ${field} }`, 'g');
                        // eslint-disable-next-line @typescript-eslint/no-explicit-any
                        tmp = tmp.replace(regExp, (this.options.templateData as Record<string, any>)[field] || '');
                    }
                    const proxyEle = document.createElement('template') as HTMLTemplateElement;
                    proxyEle.innerHTML = tmp;
                    this.dialogEle.appendChild(proxyEle.content);

                    // ...
                } else {
                    this.dialogEle.appendChild(this.slotTemplateEle.content.cloneNode(true));
                }
            }

            document.body.appendChild(this.dialogEle);
        }
    }

    /**
     * 设置元素相关属性
     */
    setDialogEleAttrs(): void {
        if (this.dialogEle) {
            if (this.options.id) {
                this.dialogEle.id = this.options.id;
            }
            if (this.options.className) {
                this.dialogEle.className += ` ${this.options.className}`;
            }
            if (this.options.innerClassName && this.dialogWrapEle) {
                this.dialogWrapEle.className += ` ${this.options.innerClassName}`;
            }
        }
    }
}

export default Dialog;
